/* 
 * Style Library / panels.js
 *
 * GUI classes to manage HTML input controls of the various property editor panels.
 */

 // Fill a dropdown list with values, optionally add empty entry at start.
// ddl: dropdown list elemnent
// values: array of strings to fill in the list
// addEmpty bool: add an empty option at the start
// cutName char: cut the displayed name at this char instead adding same name/value (e.g. cut at first comma)
function fillDropdown(ddl, values, addEmpty, langStrings) {
	//var ddl = document.getElementById(ddlID);
	ddl.options.length = 0;
	if (addEmpty) {
		ddl.options[0] = new Option("", "");
	}
	for (var i = 0; i < values.length; i++) {
		var displayName = values[i];
		if (langStrings) {
			displayName = langStrings[i];
		}
		ddl.options[ddl.options.length] = new Option(displayName, values[i]);
	}
}

/* FONT SELECTOR PANEL */

// Class to manage input controls of the font properties panel
function simpleFontSelect()
{
	var editedRule = null; // CSS rule to save changes into

	this.init = function(ed)
	{
		var fontFamilyList = ed.getParam("stylelibrary_fontfamilylist",		
			"Andale Mono=Andale Mono, monospace;" +
			"Arial=Arial, Helvetica, sans-serif;" +
			"Arial Black=Arial Black, Avant garde, sans-serif;" +
			"Arial Narrow=Arial Narrow, sans-serif;" +
			"Book Antiqua=Book Antiqua, Palatino, serif;" +
			"Brush Script MT=Brush Script MT, cursive;" +
			"Comic Sans MS=Comic Sans MS, cursive;" +
			"Courier=Courier, monospace;" +
			"Courier New=Courier New, monospace;" +
			"Helvetica=Helvetica, sans-serif;" +
			"Garamond=Garamond, serif;" +
			"Georgia=Georgia, Palatino, serif;" +
			"Impact=Impact, Chicago, sans-serif;" +
			"Lucida=Lucida, sans-serif;" +
			"Lucida Sans=Lucida Sans, sans-serif;" +
			"Lucida Console=Lucida Console, monospace;" +
			"Palatino=Palatino, serif;" +
			"Palatino Linotype=Palatino Linotype, serif;" +
			"Tahoma=Tahoma, sans-serif;" +
			"Times=Times, serif;" +
			"Times New Roman=Times New Roman, Times, serif;" +
			"Trebuchet MS=Trebuchet MS, Geneva, sans-serif;" +
			"Verdana=Verdana, Geneva, sans-serif;").split(";");
		
		var fontSizeList = ed.getParam("stylelibrary_fontsizelist", 
			"80%,90%,100%,110%,120%,135%,150%,175%,200%,250%,300%").split(",");
		
		var lineHeightList = ed.getParam("stylelibrary_lineheightlist",
			"normal,80%,90%,100%,110%,120%,140%,160%,200%").split(",");
		
		var indentList = ed.getParam("stylelibrary_indentlist",
			"0,0.5em,1em,1.5em,2em,3em").split(",");
	
		// Init size and other dropdown lists
		fillDropdown(document.getElementById('ddlFontSize'), fontSizeList, true);
		fillDropdown(document.getElementById('ddlLineHeight'), lineHeightList, true);
		fillDropdown(document.getElementById('ddlIndent'), indentList, true);

		// Init color pickers
		document.getElementById('fontcolor_pickcontainer').innerHTML = getColorPickerHTML('fontcolor_pick','fontcolor');
		document.getElementById('textshadowcolor_pickcontainer').innerHTML = getColorPickerHTML('textshadowcolor_pick','textshadowcolor');
		//document.getElementById('linkcolor_pickcontainer').innerHTML = getColorPickerHTML('linkcolor_pick','linkcolor');
		//document.getElementById('vlinkcolor_pickcontainer').innerHTML = getColorPickerHTML('vlinkcolor_pick','vlinkcolor');

		for(var i = 0; i < fontFamilyList.length; i++)
		{
			var split = fontFamilyList[i].split("=");
			o = addSelectValue(document.forms[0], "ddlFontFamily", split[0], split[1]);
			o.style.fontFamily = split[1];
		}
	
	}
	
	// Copy all values from a designer rule object to the input controls.
	this.initFromRule = function(dRule) {
		this.editedRule = dRule;
		this.setColor(dRule.getProperty("color"));
		this.setFamily(dRule.getProperty("font-family"));
		this.setSize(dRule.getProperty("font-size"));
		this.setLineHeight(dRule.getProperty("line-height"));
		this.setIndent(dRule.getProperty("text-indent"));
		this.setBold(dRule.getProperty('font-weight'));
		this.setItalic(dRule.getProperty('font-style'));
		this.setTextShadow(dRule.getProperty('text-shadow'));
	}

	// Copy all input controls into a designer rule object.
	this.saveToRule = function() {
		this.editedRule.setProperty('color', this.getColor());
		this.editedRule.setProperty('font-family', this.getFamily());
		this.editedRule.setProperty('font-size', this.getSize());
		this.editedRule.setProperty('line-height', this.getLineHeight());
		this.editedRule.setProperty('text-indent', this.getIndent());
		this.editedRule.setProperty('font-weight', this.getBold());
		this.editedRule.setProperty('font-style', this.getItalic());
		this.editedRule.setProperty('text-shadow', this.getTextShadow());
	}
	
	// VALUE VALIDATION (call before getting values!)
	// Displays alert and returns false on error.
	this.validate = function()
	{
		var val = this.getSize();
		if(val && !Validator.isFontSize(val))
		{
			alert(tinyMCEPopup.editor.getLang('stylelibrary_dlg.font_size_invalid') + "\n\n" + tinyMCEPopup.editor.getLang('stylelibrary_dlg.must_be_css_value'));
			return false;
		}
		
		val = this.getLineHeight();
		if(val && !Validator.isLineHeight(val))
		{
			alert(tinyMCEPopup.editor.getLang('stylelibrary_dlg.line_height_invalid') + "\n\n" + tinyMCEPopup.editor.getLang('stylelibrary_dlg.must_be_css_value'));
			return false;
		}
		
		val = this.getIndent();
		if(val && !Validator.isSize(val))
		{
			alert(tinyMCEPopup.editor.getLang('stylelibrary_dlg.indent_invalid') + "\n\n" + tinyMCEPopup.editor.getLang('stylelibrary_dlg.must_be_css_value'));
			return false;
		}
		
		return true;
	}

	// PUBLIC VALUE GETTERS/SETTERS

	// Get/set selected or entered font size css size value
	this.getSize = function()
	{
		return getSelectValue(document.forms[0], "ddlFontSize");
	}
	this.setSize = function(value)
	{
		selectByValue(document.forms[0], "ddlFontSize", value, true);
	}

	// Get/set selected or entered line height css size value
	this.getLineHeight = function()
	{
		return getSelectValue(document.forms[0], "ddlLineHeight");
	}
	this.setLineHeight = function(value)
	{
		selectByValue(document.forms[0], "ddlLineHeight", value, true);
	}

	// Get/set selected or entered line height css size value
	this.getIndent = function()
	{
		return getSelectValue(document.forms[0], "ddlIndent");
	}
	this.setIndent = function(value)
	{
		selectByValue(document.forms[0], "ddlIndent", value, true);
	}
	
	// Get/set 'bold' 'normal' or ''.
	this.getBold = function()
	{
		return getSelectValue(document.forms[0], "ddlFontWeight");
	}
	this.setBold = function(value)
	{
		selectByValue(document.forms[0], "ddlFontWeight", value, true);
	}

	// Get/set 'italic' 'normal' or ''.
	this.getItalic = function()
	{
		return getSelectValue(document.forms[0], "ddlFontStyle");
	}
	this.setItalic = function(value)
	{
		selectByValue(document.forms[0], "ddlFontStyle", value, true);
	}
	
	// Get the currently selected font face's value (from the currently selected list)
	this.getFamily = function()
	{
		return getSelectValue(document.forms[0], "ddlFontFamily");
	}

	// Set the multiple font family dropdown to a value.
	this.setFamily = function(family)
	{
		selectByValue(document.forms[0], "ddlFontFamily", family, true);
	}

	// Text shadow, format: "x y blur color" (blur optional).
	this.getTextShadow = function()
	{
		var x = document.getElementById("textshadow_x").value;
		var y = document.getElementById("textshadow_y").value;
		var blur = document.getElementById("textshadow_blur").value;
		var col = document.getElementById("textshadowcolor").value;

		if(x === "" || y === "" || col === "") { return ""; }

		return x + "px " + y + "px " + (blur ? blur + "px " : "") + col;
	}
	this.setTextShadow = function(shadow)
	{
		this.clearTextShadow();
		if(shadow) {
			if(shadow.trim) { shadow = shadow.trim(); } // IE9+
			var parts = shadow.split(/\s+/);
			if(parts.length > 1) {
				// x and y mandatory.
				document.getElementById("textshadow_x").value = parts[0].replace("px", "");
				document.getElementById("textshadow_y").value = parts[1].replace("px", "");

				// blur and/or color optional
				if(parts.length > 2) {
					// 3rd element is either blur or color
					if(Validator.isSize(parts[2])) {
						document.getElementById("textshadow_blur").value = parts[2].replace("px", "");
						if(parts.length > 3) {
							// 4th element is color
							document.getElementById("textshadowcolor").value = parts[3];
						}
					} else {
						// 3rd element is color
						document.getElementById("textshadowcolor").value = parts[2];
					}
				}
			}
		}
	}
	this.clearTextShadow = function() 
	{
		document.getElementById("textshadow_x").value = "";
		document.getElementById("textshadow_y").value = "";
		document.getElementById("textshadow_blur").value = "";
		document.getElementById("textshadowcolor").value = "";
	}

	// Get/set font color
	this.getColor = function()
	{
		return document.getElementById("fontcolor").value;
	}
	this.setColor = function(col)
	{
		document.getElementById("fontcolor").value = col;
		updateColor('fontcolor_pick','fontcolor');
	}
	this.delColors = function()
	{
		document.getElementById("fontcolor").value = "";
		updateColor('fontcolor_pick','fontcolor');
	}
	this.delLinkColors = function()
	{
		document.getElementById("linkcolor").value = "";
		updateColor('linkcolor_pick','linkcolor');
	}
	this.delVLinkColors = function()
	{
		document.getElementById("vlinkcolor").value = "";
		updateColor('vlinkcolor_pick','vlinkcolor');
	}
}

/* CELL or BOX PROPERTIES PANEL */

// Class to manage input controls of the cell properties panel
function simpleCellProperties()
{
	var editedRule = null; // CSS rule to save changes into

	this.init = function(ed)
	{
		// Init color pickers
		document.getElementById('boxcolor_pickcontainer').innerHTML = getColorPickerHTML('boxcolor_pick','boxcolor');
		document.getElementById('boxshadowcolor_pickcontainer').innerHTML = getColorPickerHTML('boxshadowcolor_pick','boxshadowcolor');
	}

	// Copy all values from a designer rule object to the input controls.
	this.initFromRule = function(dRule) {
		this.editedRule = dRule;

		function show(id) { document.getElementById(id).style.display = 'block'; }
		function hide(id) { document.getElementById(id).style.display = 'none'; }

		// text-align
		if(dRule.properties.has('text-align')) {
			show("divTextAlign");
			this.setTextAlign(dRule.getProperty('text-align'));
		} else {
			hide("divTextAlign");
		}
		
		// vertical-align
		if(dRule.properties.has('vertical-align')) {
			show("divVerticalAlign");
			this.setVerticalAlign(dRule.getProperty('vertical-align'));
		} else {
			hide("divVerticalAlign");
		}
		
		// padding (all or none)
		if(dRule.properties.has('padding-top') || dRule.properties.has('padding-right') ||
			dRule.properties.has('padding-bottom') || dRule.properties.has('padding-left')) {

			show("divPadding");
			
			// Same on all sides or different
			if(dRule.getProperty('padding-top') == dRule.getProperty('padding-right') &&
				dRule.getProperty('padding-top') == dRule.getProperty('padding-bottom') &&
				dRule.getProperty('padding-top') == dRule.getProperty('padding-left')) {
				this.setSamePadding(true);
				this.setPaddingTop(dRule.getProperty('padding-top'));
			} else {
				this.setSamePadding(false);
				this.setPaddingTop(dRule.getProperty('padding-top'));
				this.setPaddingRight(dRule.getProperty('padding-right'));
				this.setPaddingBottom(dRule.getProperty('padding-bottom'));
				this.setPaddingLeft(dRule.getProperty('padding-left'));
			}
		} else {
			hide("divPadding");
		}

		// border radius (all or none)
		if(dRule.properties.has('border-top-left-radius') || dRule.properties.has('border-top-right-radius') ||
			dRule.properties.has('border-bottom-left-radius') || dRule.properties.has('border-bottom-right-radius')) {

			show("divRadius");
			
			// Same on all sides or different
			if(dRule.getProperty('border-top-left-radius') == dRule.getProperty('border-top-right-radius') &&
				dRule.getProperty('border-top-left-radius') == dRule.getProperty('border-bottom-left-radius') &&
				dRule.getProperty('border-top-left-radius') == dRule.getProperty('border-bottom-right-radius')) {
				this.setSameRadius(true);
				this.setRadiusTopLeft(dRule.getProperty('border-top-left-radius'));
			} else {
				this.setSameRadius(false);
				this.setRadiusTopLeft(dRule.getProperty('border-top-left-radius'));
				this.setRadiusTopRight(dRule.getProperty('border-top-right-radius'));
				this.setRadiusBottomLeft(dRule.getProperty('border-bottom-left-radius'));
				this.setRadiusBottomRight(dRule.getProperty('border-bottom-right-radius'));
			}
		} else {
			hide("divRadius");
		}

		// background-color
		if(dRule.properties.has('background-color')) {
			show("divCellBackgroundColor");
			this.setColor(dRule.getProperty('background-color'));
		} else {
			hide("divCellBackgroundColor");
		}

		// box shadow
		if(dRule.properties.has('box-shadow')) {
			show("divBoxShadow");
			this.setBoxShadow(dRule.getProperty('box-shadow'));
		} else {
			hide("divBoxShadow");
		}
		
		// width
		if(dRule.properties.has('width')) {
			show("divWidth");
			this.setWidth(dRule.getProperty('width'));
		} else {
			hide("divWidth");
		}

		// min-height
		if(dRule.properties.has('min-height')) {
			show("divMinHeight");
			this.setMinHeight(dRule.getProperty('min-height'));
		} else {
			hide("divMinHeight");
		}
		
	}

	// Copy all input controls into a designer rule object.
	this.saveToRule = function() 
	{
		this.editedRule.setProperty('text-align', this.getTextAlign())
		this.editedRule.setProperty('vertical-align', this.getVerticalAlign());
		this.editedRule.setProperty('padding-top', this.getPaddingTop());
		this.editedRule.setProperty('padding-right', this.getPaddingRight());
		this.editedRule.setProperty('padding-bottom', this.getPaddingBottom());
		this.editedRule.setProperty('padding-left', this.getPaddingLeft());
		this.editedRule.setProperty('border-top-left-radius', this.getRadiusTopLeft());
		this.editedRule.setProperty('border-top-right-radius', this.getRadiusTopRight());
		this.editedRule.setProperty('border-bottom-left-radius', this.getRadiusBottomLeft());
		this.editedRule.setProperty('border-bottom-right-radius', this.getRadiusBottomRight());
		this.editedRule.setProperty('background-color', this.getColor());
		this.editedRule.setProperty('width', this.getWidth());
		this.editedRule.setProperty('min-height', this.getMinHeight());
		this.editedRule.setProperty('box-shadow', this.getBoxShadow());
	}
	
	// VALUE VALIDATION (call before getting values!)
	// Displays alert and returns false on error.
	this.validate = function()
	{
		// Padding
		var val = this.getPaddingTop();
		if(val && !Validator.isSize(val))
		{
			alert(tinyMCEPopup.editor.getLang('stylelibrary_dlg.padding_top_invalid') + "\n\n" + tinyMCEPopup.editor.getLang('stylelibrary_dlg.must_be_integer'));
			return false;
		}
		val = this.getPaddingBottom();
		if(val && !Validator.isSize(val))
		{
			alert(tinyMCEPopup.editor.getLang('stylelibrary_dlg.padding_bottom_invalid') + "\n\n" + tinyMCEPopup.editor.getLang('stylelibrary_dlg.must_be_integer'));
			return false;
		}
		val = this.getPaddingLeft();
		if(val && !Validator.isSize(val))
		{
			alert(tinyMCEPopup.editor.getLang('stylelibrary_dlg.padding_left_invalid') + "\n\n" + tinyMCEPopup.editor.getLang('stylelibrary_dlg.must_be_integer'));
			return false;
		}
		val = this.getPaddingRight();
		if(val && !Validator.isSize(val))
		{
			alert(tinyMCEPopup.editor.getLang('stylelibrary_dlg.padding_right_invalid') + "\n\n" + tinyMCEPopup.editor.getLang('stylelibrary_dlg.must_be_integer'));
			return false;
		}

		// Border radius
		var val = this.getRadiusTopLeft();
		if(val && !Validator.isSize(val))
		{
			alert(tinyMCEPopup.editor.getLang('stylelibrary_dlg.radius_top_left_invalid') + "\n\n" + tinyMCEPopup.editor.getLang('stylelibrary_dlg.must_be_integer'));
			return false;
		}
		val = this.getRadiusTopRight();
		if(val && !Validator.isSize(val))
		{
			alert(tinyMCEPopup.editor.getLang('stylelibrary_dlg.radius_top_right_invalid') + "\n\n" + tinyMCEPopup.editor.getLang('stylelibrary_dlg.must_be_integer'));
			return false;
		}
		val = this.getRadiusBottomLeft();
		if(val && !Validator.isSize(val))
		{
			alert(tinyMCEPopup.editor.getLang('stylelibrary_dlg.radius_bottom_left_invalid') + "\n\n" + tinyMCEPopup.editor.getLang('stylelibrary_dlg.must_be_integer'));
			return false;
		}
		val = this.getRadiusBottomRight();
		if(val && !Validator.isSize(val))
		{
			alert(tinyMCEPopup.editor.getLang('stylelibrary_dlg.radius_bottom_right_invalid') + "\n\n" + tinyMCEPopup.editor.getLang('stylelibrary_dlg.must_be_integer'));
			return false;
		}

		// Width
		val = this.getWidth();
		if(val && !Validator.isSize(val))
		{
			alert(tinyMCEPopup.editor.getLang('stylelibrary_dlg.width_invalid') + "\n\n" + tinyMCEPopup.editor.getLang('stylelibrary_dlg.must_be_css_value'));
			return false;
		}

		val = this.getMinHeight();
		if(val && !Validator.isSize(val))
		{
			alert(tinyMCEPopup.editor.getLang('stylelibrary_dlg.min_height_invalid') + "\n\n" + tinyMCEPopup.editor.getLang('stylelibrary_dlg.must_be_css_value'));
			return false;
		}
		return true;
	}
	
	this.samePaddingClicked = function()
	{
		var same = document.getElementById('chkSamePadding').checked;
		document.getElementById('ddlPaddingRight').disabled = same;
		document.getElementById('ddlPaddingLeft').disabled = same;
		document.getElementById('ddlPaddingBottom').disabled = same;
		if(same) {
			this.setPaddingLeft("");
			this.setPaddingRight("");
			this.setPaddingBottom("");
			document.getElementById("lblPaddingTop").style.display = "none";
			document.getElementById('divPaddingBottom').style.display = "none";
			document.getElementById('divPaddingLeft').style.display = "none";
			document.getElementById('divPaddingRight').style.display = "none";
		} else {
			var p = this.getPaddingTop();
			this.setPaddingLeft(p);
			this.setPaddingRight(p);
			this.setPaddingBottom(p);
			document.getElementById("lblPaddingTop").style.display = "table-cell";
			document.getElementById('divPaddingBottom').style.display = "table-row";
			document.getElementById('divPaddingLeft').style.display = "table-row";
			document.getElementById('divPaddingRight').style.display = "table-row";
		}
	}

	this.sameRadiusClicked = function() {
		var same = document.getElementById('chkSameRadius').checked;
		document.getElementById('ddlRadiusTopRight').disabled = same;
		document.getElementById('ddlRadiusBottomLeft').disabled = same;
		document.getElementById('ddlRadiusBottomRight').disabled = same;
		if(same) {
			this.setRadiusTopRight("");
			this.setRadiusBottomLeft("");
			this.setRadiusBottomRight("");
			document.getElementById('lblRadiusTopLeft').style.display = "none";
			document.getElementById('divRadiusTopRight').style.display = "none";
			document.getElementById('divRadiusBottomLeft').style.display = "none";
			document.getElementById('divRadiusBottomRight').style.display = "none";
		} else {
			var p = this.getRadiusTopLeft();
			this.setRadiusTopRight(p);
			this.setRadiusBottomLeft(p);
			this.setRadiusBottomRight(p);
			document.getElementById('lblRadiusTopLeft').style.display = "table-cell";
			document.getElementById('divRadiusTopRight').style.display = "table-row";
			document.getElementById('divRadiusBottomLeft').style.display = "table-row";
			document.getElementById('divRadiusBottomRight').style.display = "table-row";
		}
	}
	
	// PUBLIC VALUE GETTERS/SETTERS

	// Get/set selected or entered padding values
	this.getPaddingTop = function()
	{
		var val = document.getElementById("ddlPaddingTop").value;
		return val + (val === "" ? "" : "px");
	}
	this.setPaddingTop = function(value)
	{
		document.getElementById("ddlPaddingTop").value = value.replace("px", "");
	}
	this.getPaddingRight = function()
	{
		if(this.getSamePadding())
		{
			return this.getPaddingTop();
		}
		else
		{
			var val = document.getElementById("ddlPaddingRight").value;
			return val + (val === "" ? "" : "px");
		}
	}
	this.setPaddingRight = function(value)
	{
		document.getElementById("ddlPaddingRight").value = value.replace("px", "");
	}
	this.getPaddingBottom = function()
	{
		if(this.getSamePadding())
		{
			return this.getPaddingTop();
		}
		else
		{
			var val = document.getElementById("ddlPaddingBottom").value;
			return val + (val === "" ? "" : "px");
		}
	}
	this.setPaddingBottom = function(value)
	{
		document.getElementById("ddlPaddingBottom").value = value.replace("px", "");
	}
	this.getPaddingLeft = function()
	{
		if(this.getSamePadding())
		{
			return this.getPaddingTop();
		}
		else
		{
			var val = document.getElementById("ddlPaddingLeft").value;
			return val + (val === "" ? "" : "px");
		}
	}
	this.setPaddingLeft = function(value)
	{
		document.getElementById("ddlPaddingLeft").value = value.replace("px", "");
	}

	// Get/set selected or entered RADIUS values
	this.getSameRadius = function()
	{
		return document.getElementById("chkSameRadius").checked;
	}
	this.setSameRadius = function(value)
	{
		document.getElementById("chkSameRadius").checked = value;
		this.sameRadiusClicked();
	}
	this.getRadiusTopLeft = function()
	{
		var val = document.getElementById("ddlRadiusTopLeft").value;
		return val + (val === "" ? "" : "px");
	}
	this.setRadiusTopLeft = function(value)
	{
		document.getElementById("ddlRadiusTopLeft").value = value.replace("px", "");
	}
	this.getRadiusTopRight = function()
	{
		if(this.getSameRadius())
		{
			return this.getRadiusTopLeft();
		}
		else
		{
			var val = document.getElementById("ddlRadiusTopRight").value;
			return val + (val === "" ? "" : "px");
		}
	}
	this.setRadiusTopRight = function(value)
	{
		document.getElementById("ddlRadiusTopRight").value = value.replace("px", "");
	}
	this.getRadiusBottomLeft = function()
	{
		if(this.getSameRadius())
		{
			return this.getRadiusTopLeft();
		}
		else
		{
			var val = document.getElementById("ddlRadiusBottomLeft").value;
			return val + (val === "" ? "" : "px");
		}
	}
	this.setRadiusBottomLeft = function(value)
	{
		document.getElementById("ddlRadiusBottomLeft").value = value.replace("px", "");
	}
	this.getRadiusBottomRight = function()
	{
		if(this.getSameRadius())
		{
			return this.getRadiusTopLeft();
		}
		else
		{
			var val = document.getElementById("ddlRadiusBottomRight").value;
			return val + (val === "" ? "" : "px");
		}
	}
	this.setRadiusBottomRight = function(value)
	{
		document.getElementById("ddlRadiusBottomRight").value = value.replace("px", "");
	}

	// Get/set selected vertical alignment
	this.getVerticalAlign = function()
	{
		return getSelectValue(document.forms[0], "ddlVerticalAlign");
	}
	this.setVerticalAlign = function(value)
	{
		selectByValue(document.forms[0], "ddlVerticalAlign", value, true);
	}

	// Get/set selected text alignment
	this.getTextAlign = function()
	{
		return getSelectValue(document.forms[0], "ddlTextAlign");
	}
	this.setTextAlign = function(value)
	{
		selectByValue(document.forms[0], "ddlTextAlign", value, true);
	}
	this.getSamePadding = function()
	{
		return document.getElementById("chkSamePadding").checked;
	}
	this.setSamePadding = function(value)
	{
		document.getElementById("chkSamePadding").checked = value;
		this.samePaddingClicked();
	}

	// Get set box background color
	this.getColor = function()
	{
		return document.getElementById("boxcolor").value;
	}
	this.setColor = function(col)
	{
		document.getElementById("boxcolor").value = col;
		updateColor('boxcolor_pick','boxcolor');
	}
	this.delColors = function()
	{
		document.getElementById("boxcolor").value = "";
		updateColor('boxcolor_pick','boxcolor');
	}
	
	// Box shadow, format: "x y blur spread color inset" (blur, spread, inset are optional).
	this.getBoxShadow = function()
	{
		var x = document.getElementById("boxshadow_x").value;
		var y = document.getElementById("boxshadow_y").value;
		var blur = document.getElementById("boxshadow_blur").value;
		var spread  = document.getElementById("boxshadow_spread").value;
		var inset =  document.getElementById("boxshadow_inset").checked;
		var col = document.getElementById("boxshadowcolor").value;

		if(x === "" || y === "" || col === "") { return ""; }

		return x + "px " + y + "px " + (blur ? blur + "px " : "") 
			+ (spread ? spread + "px " : "") + col + (inset ? " inset" : "");
	}
	this.setBoxShadow = function(shadow)
	{
		this.clearBoxShadow();
		if(shadow) {
			if(shadow.trim) { shadow = shadow.trim(); } // IE9+
			var parts = shadow.split(/\s+/);
			var p;

			// "x y blur spread color inset" 
			if(parts.length > 1) {
				// x and y mandatory.
				document.getElementById("boxshadow_x").value = parts.shift().replace("px", "");
				document.getElementById("boxshadow_y").value = parts.shift().replace("px", "");

				// 3rd element is either blur or color or inset
				if(parts.length > 0) {
					p = parts.shift();
					if(Validator.isSize(p)) {
						document.getElementById("boxshadow_blur").value = p.replace("px", "");
					} else if(p != 'inset') {
						document.getElementById("boxshadowcolor").value = p;
					}
				}

				// 4rd element is either blur or color or inset
				if(parts.length > 0) {
					p = parts.shift();
					if(Validator.isSize(p)) {
						document.getElementById("boxshadow_spread").value = p.replace("px", "");
					} else if(p != 'inset') {
						document.getElementById("boxshadowcolor").value = p;
					}
				}

				// 4rd element is either color or inset
				if(parts.length > 0) {
					p = parts.shift();
					if(p != 'inset') {
						document.getElementById("boxshadowcolor").value = p;
					}
				}
			}
			document.getElementById("boxshadow_inset").checked = (shadow.indexOf("inset") != -1);
		}
	}
	this.clearBoxShadow = function() 
	{
		document.getElementById("boxshadow_x").value = "";
		document.getElementById("boxshadow_y").value = "";
		document.getElementById("boxshadow_blur").value = "";
		document.getElementById("boxshadow_spread").value = "";
		document.getElementById("boxshadowcolor").value = "";
		document.getElementById("boxshadow_inset").checked = false;
	}

	// Get/set width and min-height
	this.getWidth = function() {
		return this._parseCssSize(document.getElementById('txtWidth').value);
	}
	this.setWidth = function(width) {
		document.getElementById('txtWidth').value = this._parseCssSize(width);
	}
	this.getMinHeight = function() {
		return this._parseCssSize(document.getElementById('txtMinHeight').value);
	}
	this.setMinHeight = function(height) {
		document.getElementById('txtMinHeight').value = this._parseCssSize(height);
	}
	
	// Add "px" default unit when necessary
	this._parseCssSize = function(s) {
		if(String(s).match(/^[0-9]+$/)) { 
			return s + "px";
		}
		return s;
	}
}

/* MARGIN PROPERTIES PANEL */

// Class to manage controls of the margin properties panel
function simpleMarginPicker()
{
	var editedRule = null; // CSS rule to save changes into

	this.init = function(ed)
	{
		// Settings
		var marginList = ed.getParam("stylelibrary_marginlist",
			 "0,1px,2px,5px,10px,15px,20px,30px,0.5em,1em,2em").split(",");
	
		// Init size and other dropdown lists
		fillDropdown(document.getElementById('ddlMarginTop'), marginList, true);
		fillDropdown(document.getElementById('ddlMarginBottom'), marginList, true);
		fillDropdown(document.getElementById('ddlMarginLeft'), marginList, true);
		fillDropdown(document.getElementById('ddlMarginRight'), marginList, true);
	}

	// Copy all values from a designer rule object to the input controls.
	this.initFromRule = function(dRule) {
		this.editedRule = dRule;

		function show(id) { document.getElementById(id).style.display = 'block'; }
		function hide(id) { document.getElementById(id).style.display = 'none'; }

		// margin-top
		if(dRule.properties.has('margin-top')) {
			show("divMarginTop");
			this.setMarginTop(dRule.getProperty('margin-top'));
		} else {
			hide("divMarginTop");
		}

		// margin-bottom
		if(dRule.properties.has('margin-bottom')) {
			show("divMarginBottom");
			this.setMarginBottom(dRule.getProperty('margin-bottom'));
		} else {
			hide("divMarginBottom");
		}
		
		// margin-left
		if(dRule.properties.has('margin-left')) {
			show("divMarginLeft");
			this.setMarginLeft(dRule.getProperty('margin-left'));
		} else {
			hide("divMarginLeft");
		}
		
		// margin-right
		if(dRule.properties.has('margin-right')) {
			show("divMarginRight");
			this.setMarginRight(dRule.getProperty('margin-right'));
		} else {
			hide("divMarginRight");
		}

	}
	
	// Copy all input controls into a designer rule object.
	this.saveToRule = function() {
		this.editedRule.setProperty('margin-top', this.getMarginTop());
		this.editedRule.setProperty('margin-bottom', this.getMarginBottom());
		this.editedRule.setProperty('margin-left', this.getMarginLeft());
		this.editedRule.setProperty('margin-right', this.getMarginRight());
	}
	
	// VALUE VALIDATION (call before getting values!)
	// Displays alert and returns false on error.
	this.validate = function()
	{
		var val = this.getMarginTop();
		if(val && !Validator.isMarginWidth(val))
		{
			alert(tinyMCEPopup.editor.getLang('stylelibrary_dlg.margin_top_invalid') +
				"\n\n" + tinyMCEPopup.editor.getLang('stylelibrary_dlg.must_be_css_value'));
			return false;
		}
		
		val = this.getMarginBottom();
		if(val && !Validator.isMarginWidth(val))
		{
			alert(tinyMCEPopup.editor.getLang('stylelibrary_dlg.margin_bottom_invalid') +
				"\n\n" + tinyMCEPopup.editor.getLang('stylelibrary_dlg.must_be_css_value'));
			return false;
		}
		
		val = this.getMarginLeft();
		if(val && !Validator.isMarginWidth(val))
		{
			alert(tinyMCEPopup.editor.getLang('stylelibrary_dlg.margin_left_invalid') +
				"\n\n" + tinyMCEPopup.editor.getLang('stylelibrary_dlg.must_be_css_value'));
			return false;
		}
		
		val = this.getMarginRight();
		if(val && !Validator.isMarginWidth(val))
		{
			alert(tinyMCEPopup.editor.getLang('stylelibrary_dlg.margin_right_invalid') +
				"\n\n" + tinyMCEPopup.editor.getLang('stylelibrary_dlg.must_be_css_value'));
			return false;
		}
		return true;
	}

	// PUBLIC VALUE GETTERS/SETTERS

	this.getMarginTop = function()
	{
		return getSelectValue(document.forms[0], "ddlMarginTop");
	}
	this.setMarginTop = function(value)
	{
		selectByValue(document.forms[0], "ddlMarginTop", value, true);
	}
	this.getMarginBottom = function()
	{
		return getSelectValue(document.forms[0], "ddlMarginBottom");
	}
	this.setMarginBottom = function(value)
	{
		selectByValue(document.forms[0], "ddlMarginBottom", value, true);
	}
	this.getMarginLeft = function()
	{
		return getSelectValue(document.forms[0], "ddlMarginLeft");
	}
	this.setMarginLeft = function(value)
	{
		selectByValue(document.forms[0], "ddlMarginLeft", value, true);
	}
	this.getMarginRight = function()
	{
		return getSelectValue(document.forms[0], "ddlMarginRight");
	}
	this.setMarginRight = function(value)
	{
		selectByValue(document.forms[0], "ddlMarginRight", value, true);
	}
}

/* BORDER PROPERTIES */

// Class to manage input controls of the border properties panel
function simpleBorderPicker()
{
	// Constructor and member variables
	var allowIncomplete = true;	// Allow incomplete border speficiation on .validate()
	var editedRule = null; // CSS rule to save changes into

	this.init = function(ed)
	{
		// Init color pickers
		document.getElementById('bordercolor_pickcontainer').innerHTML = getColorPickerHTML('bordercolor_pick','bordercolor');
	}
	
	// Copy all values from a designer rule object to the input controls.
	this.initFromRule = function(dRule)
	{
		this.editedRule = dRule; // Store CSS rule reference to save to this on changes
		var borders = dRule.properties.compareBorders();
		this.setAllSides( (borders == "b" || borders == "-") );
		this.loadFromRule();
	}

	// Load CSS data into form controls
	this.loadFromRule = function()
	{
		var side = this.getSide();
		if(!side) { side = "top"; }
		this.setWidth(this.editedRule.getProperty("border-" + side + "-width"));
		this.setColor(this.editedRule.getProperty("border-" + side + "-color"));
		this.setStyle(this.editedRule.getProperty("border-" + side + "-style"));
	}

	// Called when side selector control is clicked
	this.selectSideClicked = function(e) 
	{
		var parentOffset = $("#borderwrap").parent().offset();
		var posX = (e.pageX - parentOffset.left);
		var posY = (e.pageY - parentOffset.top);
		if(posY < 15) {
			$("#borderwrap").removeClass().addClass("top");
			this.loadFromRule();
		} else if(posY > 65) {
			$("#borderwrap").removeClass().addClass("bottom");
			this.loadFromRule();
		} else if(posX < 15) {
			$("#borderwrap").removeClass().addClass("left");
			this.loadFromRule();
		} else if(posX > 65) {
			$("#borderwrap").removeClass().addClass("right");
			this.loadFromRule();
		} else if(posX > 20 && posX < 60 && posY > 20 && posY < 60) {
			if($("#borderwrap").is(".top,.bottom,.left,.right")) {
				$("#borderwrap").removeClass();
			} else {
				$("#borderwrap").removeClass().addClass("top");
			}
			this.loadFromRule();
		}
	}

	// Copy all input controls into a designer rule object.
	this.saveToRule = function() {
	
		var t = this;
		function applySide(borderSide) {
			t.editedRule.setProperty(borderSide+"-width", t.getWidth());
			t.editedRule.setProperty(borderSide+"-color", t.getColor());
			t.editedRule.setProperty(borderSide+"-style", t.getStyle());
		}

		var side = this.getSide();
		if(side)
		{
			// Apply to one side
			applySide("border-" + side);
		}
		else
		{
			// Apply to all sides
			applySide("border-top");
			applySide("border-left");
			applySide("border-bottom");
			applySide("border-right");
		}
	}

	// Value validation (call before getting values!)
	// Displays alert and returns false on error.
	this.validate = function()
	{
		var val = this.getWidth();
		if(val && !Validator.isBorderWidth(val))
		{
			alert(tinyMCEPopup.editor.getLang('stylelibrary_dlg.border_width_invalid') + "\n\n" + tinyMCEPopup.editor.getLang('stylelibrary_dlg.must_be_integer'));
			return false;
		}

		var style = this.getStyle();
		var width = this.getWidth();
		var color = this.getColor();
		var widthPx = null;
		var pxRx = new RegExp('^([0-9]+)px$');
		if(pxRx.test(width))
		{
			widthPx = Number(width.match(pxRx)[1]);
		}
		

		// Check if style+border+width are specified together!
		if(!allowIncomplete)
		{
			var specified = 0; // Count if all 3 properties are specified.
			
			if(style != "" && style != "none")
			{
				specified++;
			}
			if(color != "")
			{
				specified++;
			}
			if(width != "0" && width != "")
			{
				specified++;
			}
			if(specified != 0 && specified != 3)
			{
				alert(tinyMCEPopup.editor.getLang('stylelibrary_dlg.border_props_incomplete'));
				return false;
			}
		}
		
		
		// Double width must be checked.
		if(style == 'double')
		{
			if(width == 'thin' || (widthPx && widthPx < 3) )
			{
				if(confirm(tinyMCEPopup.editor.getLang('stylelibrary_dlg.border_double_thin') + "\n\n" + tinyMCEPopup.editor.getLang('stylelibrary_dlg.border_double_modulo_fix')))
				{
					this.setWidth('3px');
					widthPx = 3;
					width = '3px';
				}
				else
				{
					return false;
				}
			}

			if(widthPx && (widthPx % 3 == 1))
			{
				if(confirm(tinyMCEPopup.editor.getLang('stylelibrary_dlg.border_double_modulo') + "\n\n" + tinyMCEPopup.editor.getLang('stylelibrary_dlg.border_double_modulo_fix')))
				{
					// Adjust with to thinest ok
					if(widthPx == 4)
					{
						this.setWidth('3px');
						widthPx = 3;
						width = '3px';
					}
					else
					{
						widthPx++;
						this.setWidth(widthPx + 'px');
						width = widthPx + 'px';
					}
				}
				else
				{
					return false;
				}
			}
		}
		
		// Dotted are generallly bad
		if(style == 'dotted')
		{
			if(widthPx == 1 || width == 'thin')
			{
				// Old IE6 warning removed alert(tinyMCEPopup.editor.getLang('stylelibrary_dlg.border_thin_dotted'));
			}
			else
			{
				alert(tinyMCEPopup.editor.getLang('stylelibrary_dlg.border_thick_dotted'));
			}
		}
		
		// 3D cannot be dark
		if(style == 'inset' || style == 'outset' || style == 'groove' || style == 'ridge')
		{
			if(color == '#000000')
			{
				if(confirm(tinyMCEPopup.editor.getLang('stylelibrary_dlg.border_too_dark') + "\n\n" + tinyMCEPopup.editor.getLang('stylelibrary_dlg.border_too_dark_fix')))
				{
					this.setColor('#676767');
				}
			}
		}
		
		return true;
	}
	
	// PUBLIC VALUE GETTERS/SETTERS

	this.getWidth = function()
	{
		var val = document.getElementById("ddlBorderWidth").value;
		return val + (val === "" ? "" : "px");
	}
	this.setWidth = function(value)
	{
		document.getElementById("ddlBorderWidth").value = value.replace("px", "");
	}

	// Get/set selected border style
	this.getStyle = function()
	{
		var selected = jQuery("#borderpicker input[type='radio']:checked");
		if (selected.length > 0) {
			return selected.val();
		}
		return "";
	}
	this.setStyle = function(value)
	{
		jQuery("#borderpicker input[type=radio]").removeAttr('checked');
		jQuery("#borderpicker input[value="+value+"]")[0].checked = true;
	}
	
	// Gets the checked status of the "Apply to all sides" checkbox.
	this.getAllSides = function()
	{
		return $("#borderwrap").is(".top,.bottom,.left,.right");
	}
	// Gets the currently edited side, empty string if all sides are edited together
	this.getSide = function() 
	{
		return $("#borderwrap").attr("class");
	}
	// Sets the checked status of the "Apply to all sides" checkbox.
	this.setAllSides = function(allSame)
	{
		if(allSame) {
			$("#borderwrap").removeClass();
		} else {
			$("#borderwrap").removeClass().addClass("top");
		}
	}

	// Clear all 3 border properties (skip style if this is invoked from style on-change)	
	this.clear = function(skipStyle)
	{
		if(!skipStyle)
		{
			this.setStyle('');
		}
		this.setWidth('');
		this.delColors();
	}
	
	// Get set border color
	this.getColor = function()
	{
		return document.getElementById("bordercolor").value;
	}
	this.setColor = function(col)
	{
		document.getElementById("bordercolor").value = col;
		updateColor('bordercolor_pick','bordercolor');
	}
	this.delColors = function()
	{
		document.getElementById("bordercolor").value = "";
		updateColor('bordercolor_pick','bordercolor');
	}
}

/* PREVIEW SETTINGS PANEL */

// Class to manage input controls of the preview settings.
function simplePreviewSettings()
{
	// SHOW/HIDE THE PREVIEW CONTROLS 
	this.hideTableHeaders = function()
	{
		document.getElementById("divTableHeaders").style.display = 'none';
	}
	this.showTableHeaders = function()
	{
		document.getElementById("divTableHeaders").style.display = 'block';
	}
	
	// PREVIEW CONTROL EVENTS
	
	// Show/hide surrounding border
	this.switchEdge = function(show)
	{
		var chk = document.getElementById("chkShowEdge");
		chk.checked = show;
		
		var edge = window.frames['demoFrame'].document.getElementById("documentEdge");

		if(show)
		{	
			edge.style.cssText = "border-width: 1px; border-style: dashed; border-color: #aaaaaa;"
		}
		else
		{
			edge.style.cssText = "border-width: 0;"
		}
	}

	// Justify demo text or not.
	this.switchJustify = function(show)
	{
		var chk = document.getElementById("chkJustifyDemo");
		chk.checked = show;

		var target = window.frames['demoFrame'].document;
		var lorem = jQuery("*[id^=lorem]",target);
	
		if(show)
		{
			lorem.css("text-align", "justify");
		}
		else
		{
			lorem.css("text-align", "");
		}
	}
	
	// Show/hide context elements
	this.switchLorem = function(show, quick)
	{
		var chk = document.getElementById("chkShowLorem");
		chk.checked = show;
		
		var target = window.frames['demoFrame'].document;
		var lorem = jQuery("*[id^=lorem]",target);

		if (show)
		{
			if (quick)
			{
				lorem.show();
			} else {
				lorem.slideDown('fast');
			}
		} else {
			if (quick)
			{
				lorem.hide();
			} else {
				lorem.slideUp('fast');
			}
		}
	}
	
	// Select one of the demo tables for preview
	this.selectDemoTable = function()
	{
		var type = jQuery("select#ddlDemoType option:selected").val();
		var target = window.frames['demoFrame'].document;

		jQuery("div[id^=demoTable]",target).hide();
		jQuery("div#demoTable"+type,target).show();
	}
	this.getDemoTable = function()
	{
		return jQuery("select#ddlDemoType option:selected").val();
	}

	// Show an extra note for collapsed borders
	this.switchCollapseNote = function() {
		var target = window.frames['demoFrame'].document;
		var note = jQuery("*[id=collapsenote]",target);	
		if(document.getElementById("chkCollapse").checked) {
			note.show();
		} else {
			note.hide();
		}
	}
	// Preview background color
	
	// Colorpicker calls this to set and store preview background in cookie.
	this.demoBgChanged = function()
	{
		var target = window.frames['demoFrame'].document;
		var color =  document.getElementById("previewbg").value;
		jQuery("body", target).css('background-color', color);
		
		// Store color in cookie (or clear cookie)
		var date = new Date(); // 365 days cookie
		date.setTime(date.getTime() + (365 * 24 * 60 * 60 * 1000));
		tinymce.util.Cookie.set("stylelibrary_bg", color, date, "/");
	}

	// Init designer calls this, to restore preview background from cookie.
	this.demoBgInit = function()
	{
		var col = tinymce.util.Cookie.get("stylelibrary_bg", "/");
		if(col)
		{
			// Restore from cookie
			document.getElementById("previewbg").value = col; 
		}
		updateColor('previewbg_pick','previewbg');
		this.demoBgChanged();
	}

	this.delColor = function()
	{
		document.getElementById("previewbg").value = "";
		updateColor('previewbg_pick','previewbg');
		this.demoBgChanged();
	}
}